package com.dage.salesflow.kit;

import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.util.MapUtils;
import com.jfinal.ext.kit.DateKit;
import com.jfinal.kit.Kv;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.ActiveRecordException;
import com.jfinal.plugin.activerecord.Record;
import net.sf.cglib.beans.BeanMap;

import java.lang.reflect.Field;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

public class ObjectKit {

	private static final Map<Class, Map<String, Field>> fieldMap = MapUtils.newHashMap();

	/**
	 * 获取指定类的字段map
	 *
	 * @param clazz
	 * @return
	 */
	public static Map<String, Field> getClassFieldMap(Class clazz) {
		Map<String, Field> fields = fieldMap.get(clazz);
		if (fields == null) {
			Field[] fs = clazz.getDeclaredFields();
			fields = MapUtils.newHashMapWithExpectedSize(fs.length);
			for (Field field : fs) {
				field.setAccessible(true);
				fields.put(field.getName(), field);
			}
			fieldMap.put(clazz, fields);
		}
		return fields;
	}

	/**
	 * records集合转Map集合，将包含下划线字符 '_' 的字段名转换成驼峰格式
	 *
	 * @param records
	 * @param postHandler Map转换完成后需要执行的操作
	 * @return
	 */
	public static List<Map<String, Object>> records2Maps(List<Record> records, Function<Map<String, Object>, Map<String, Object>> postHandler) {
		List<Map<String, Object>> list = ListUtils.newArrayList();
		for (Record record : records) {
			list.add(record2Map(record, postHandler));
		}
		return list;
	}

	public static List<Map<String, Object>> records2Maps(List<Record> records) {
		return records2Maps(records, null);
	}

	/**
	 * Record转Map，将包含下划线字符 '_' 的字段名转换成驼峰格式
	 *
	 * @param postHandler Map转换完成后需要执行的操作
	 * @return
	 */
	public static Map<String, Object> record2Map(Record record, Function<Map<String, Object>, Map<String, Object>> postHandler) {
		Map<String, Object> columns = record.getColumns();
		Map<String, Object> kv = Kv.create();
		for (Map.Entry<String, Object> entry : columns.entrySet()) {
			Object value = entry.getValue();
			//必须转换java.util.Date，否则excel导出报错
			if (value != null) {
				if (value.getClass() == java.sql.Date.class || value.getClass() == java.sql.Timestamp.class) {
					java.util.Date sqlDate = (java.util.Date) value;
					value = new java.util.Date(sqlDate.getTime());
					//日期格式化处理
					if (value.getClass() == java.sql.Date.class) {
						kv.put(StrKit.toCamelCase(entry.getKey()) + "Str", DateKit.toStr((Date) value, DateKit.datePattern));
					} else {
						kv.put(StrKit.toCamelCase(entry.getKey()) + "Str", DateKit.toStr((Date) value, DateKit.timeStampPattern));
					}
				}
			}
			kv.put(StrKit.toCamelCase(entry.getKey()), value);
		}
		if (postHandler != null) {
			kv = postHandler.apply(kv);
		}
		return kv;
	}

	public static Map<String, Object> record2Map(Record record) {
		return record2Map(record, null);
	}

	/**
	 * Record转Bean，将包含下划线字符 '_' 的字段名转换成驼峰格式
	 *
	 * @param postHandler Map转换完成后需要执行的操作
	 * @return
	 */
	public static <T> T record2Bean(Record record, Class<T> beanClass, Function<Map<String, Object>, Map<String, Object>> postHandler) {
		try {
			Map<String, Object> objectMap = record2Map(record, postHandler);
			T bean = beanClass.newInstance();
			BeanMap beanMap = BeanMap.create(bean);
			beanMap.putAll(objectMap);
			return bean;
		} catch (Exception e) {
			throw new ActiveRecordException(e);
		}
	}

	public static <T> T record2Bean(Record record, Class<T> beanClass) {
		return record2Bean(record, beanClass, null);
	}

	/**
	 * records集合转Bean集合，将包含下划线字符 '_' 的字段名转换成驼峰格式
	 *
	 * @param postHandler Map转换完成后需要执行的操作
	 */
	public static <T> List<T> records2Beans(List<Record> records, Class<T> beanClass, Function<Map<String, Object>, Map<String, Object>> postHandler) {
		List<T> beans = ListUtils.newArrayList();
		for (Record record : records) {
			beans.add(record2Bean(record, beanClass, postHandler));
		}
		return beans;
	}

	public static <T> List<T> records2Beans(List<Record> records, Class<T> beanClass) {
		return records2Beans(records, beanClass, null);
	}
}
